<!DOCTYPE html>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>基础知识</title>
	<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"" rel="stylesheet">
	<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/3.2.3/animate.css" rel="stylesheet">
    <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
	<link rel="stylesheet" type="text/css" href="../../static/css/public.css" />
	<style type="text/css">
		li{
			text-indent: 2em;
			list-style: none;
		}
	</style>
</head>
<body>
	<!-- 回到顶部 -->
	<div class="topBtn">
		<a href="#top">
			<i class="fa fa-long-arrow-up"></i>
		</a>
	</div>
	<!--右边内容-->
	<div id="app" class="main animated fadeInRight">
		<div class="shadow">
			<div class="Table" v-cloak id="top">
				<div class="TableRow" v-for="(el,index) in list">
					<a class="RowLeft" :href="'#'+el.id">{{el.name}}</a>
					<span class="RowRight">{{el.explain}}</span>
				</div>
			</div>
			<div>
				<h4 id="for">for</h4>
				<p> 遍历数组最常用到的for循环，是最为熟知的一种方法，
				在ES5中定义了一些新的遍历方法，更加适用于函数式编程</p>
				<pre>
	console.time('你好')
	let num=0
	for(let i=0;i&lt;1000000;i++){
		num+=1
	}
	console.timeEnd('你好')
	console.log('num:',num)
	VM654:6 你好: 6.131103515625ms
	VM654:7 num: 1000000			
				</pre>
				<h5>for...in 和 for...of</h5>
				<p>
					for..in..：也是JS循环的一种，但是<span class="red">性能很低效</span>，
					因为它会遍历数组里的每一个属性，包括不知名或者动态添加的属性，
					全部查找遍历的内存开销很大，所以再开发尽量不要用for in 。
					但是for..in..可以遍历对象的键名，将键名读取，
				</p>
				<p>
					 for...of:是ES6遍历数组Iterator（遍历器），通过内部属性next()方法，
					 读取下个属性、方法，遵循Iterator原则，对于Object.defineProperty()中
					 enumerable为false时不可读取。也会遍历数组里的每一个属性，
					 包括不知名或者动态添加的属性，
				</p>
				<pre>
	let arr1={name:'1',age:2,sex:'3'}
	    let newArr=[]
	for(let item in arr1){
		console.log(item)
	}==>		name  age	sex
	
	const arr = ['red', 'green', 'blue'];
	for(let v of arr) {
	  console.log(v); // red green blue
	}
	const obj = {};
	obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);
	for(let v of obj) {
	  console.log(v); // red green blue
	}
	
	const message = 'hello';
	
	for (const character of message) {
	  console.log(character);
	}
	// 'h'
	// 'e'
	// 'l'
	// 'l'
	// 'o'

	
	const persons2 = [
	  { name: 'John Smith' ,last:{name:'last'}},
	  { name: 'Jane Doe' }
	];
	for (const { name } of persons2) {
	  console.log(name);
	}
	// 'John Smith'
	// 'Jane Doe'
	
	const names = new Map();
	names.set(1, 'one');
	names.set(2, 'two');
	for (const [number, name] of names) {
	  console.log(number, name);
	}
	// logs 1, 'one'
	// logs 2, 'two'

				</pre>
				<p>
					它简明扼要
					它接受迭代器，包括数组，字符串，Set，Map，DOM集合
					它接受类数组对象
					迭代的项目可以在就地解构。
				</p>
			</div>
			<div>
				<h4 id="forEach">Array.forEach()</h4>
				<p>里面的三个参数,第一个是显示数组里的第一个元素,
				第二个参数是显示元素的下标(位置),第三个参数是数组本身</p>
				<p class="red">forEach没有返回值，break、continue不能停止遍历，而且还会报错，
				return false在函数中使用只是阻止了当前的函数继续执行，并不能阻断遍历过程。
				但是在数据量小于10*5时，forEach比for高效</p>
				<pre>
	var arr=[5,2,3,10,100];
	arr.forEach(function(el,index){
		console.log(el)
	});		
	
	break、continue这两个关键字只能在循环语句中使用，现在是在函数中，不能使用
	var a = [1,2,3,4,5,6,7,8,9,10];
	a.forEach(function(val, idx, arr){
	    if(val == 5)
	        break;
	}, this);
	==>Uncaught SyntaxError: Illegal break statement
	
	var a = [1,2,3,4,5,6,7,8,9,10];
	a.forEach(function(val, idx, arr){
	    console.log(arguments);
	    return false;
	}, this);		
				</pre>
				<p class="red">
					forEach能停止循环的情况，使用try{}catch{}方法，因为捕获到错误
					会停止函数执行。
				</p>
				<pre>
	try{
		var a = [1,2,3,4,5,6,7,8,9,10];
		a.forEach(function(val, idx, arr){
			if(val == 5)
				throw new Error('break')
		}, this);
	}catch (e){
		console.log(e);
	}
				</pre>
			</div>
			<div>
				<h5>forEach 中使用 await 是否有效</h5>
				<p>
					对于异步代码，forEach 并不能保证按顺序执行。
					因为forEach的 底层是以 for (var i=0;i&lt;length;i++) 
					的方式执行，for是无法中断，但是可以使用break和continue，
					return并不能跳出循环，只能出现在函数体内。
					break和continue的区别是break跳出循环，continue跳出本次循环
				</p>
				<p>
					要让for按顺序执行可以使用let，定义一个块级作用域，
					每次循环相互隔离。方法二，可以使用立即执行函数，
					在for的代码就形成了一个闭包，和let一样的效果
				</p>
				<p>
					使用 forEach、map不能中断循环，将每个循环都执行完，
					for ...in 可以遍历枚举，但对象不包括本身原型链上的属性，可以中断。
				</p>
				<p>
					当对象通过 Object.defindProperty()方法定义 emumerable 为false时，
					for ...in 不可遍历到。也可得出 Object.keys、
					Object.values、Object.entries 方法都是遍历可枚举属性组成的数组
				</p>
			</div>
			<div>
				<h4 class="" id="filter">filter()</h4>
				<pre>
	arr.filter(function(a,b,c){
		console.log(a);
		console.log(b);
		console.log(c);
		return a&lt;10;
	})	
	自定义filter()方法
	var obj={
			filter:function(str,arr){
				console.log(arr)
				var tmp=[];	
				for (var i=0;i&lt;arr.length;i++){
					console.log(arr[i])
					console.log(i)
					console.log(arr)
					if(str(arr[i],i,arr)){
						tmp.push(arr[i])
					}
				}
			return tmp;
			}
		}
				</pre>
				<p> 遍历过滤，它不会对空数组进行检测，也不会改变原始数组，
				它能通过筛选条件快速给出遍历结果，不符合条件的就不会去遍历，
				符合条件的才会遍历，极大的节省了遍历开销成本</p>
				<pre>
	let arr1=[1,2,3,4,5,6]
	function filterFN(num){
		return num>3
	}
	let newArr=arr1.filter(filterFN)			
				</pre>
			</div>
			<div>
				<h4 class="" id="find">find(currentValue, index,arr)</h4>
				<div>
				find() 方法返回通过测试（函数内判断）的数组的第一个元素的值。
				</div>
				<div>
				find() 方法为数组中的每个元素都调用一次函数执行：
					<ul>
						<li>当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素，
						之后的值不会再调用执行函数。
						</li>
						<li>如果没有符合条件的元素返回 undefined</li>
					</ul>
				</div>
				<div>
				注意: find() 对于空数组，函数是不会执行的。
				</div>
				<div>
				注意: find() 并没有改变数组的原始值。
				</div>
				<pre>
	let arr = [0,2,3,5,6,9,22,35]	
	let val = arr.find(x=>x>20)	
	console.log(val)==>22
				</pre>
			</div>
			<div>
				<h4 class="" id="every">every()</h4>
				<pre>
	function isBigEnough(element, index, array) {
	  return element >= 10;
	}			
	[12, 5, 8, 130, 44].every(isBigEnough);   // false
	[12, 54, 18, 130, 44].every(isBigEnough); // true
				</pre>
			</div>
			<div>
				<h4 class="" id="some">some()</h4>
				<pre>
	function isBiggerThan10(element, index, array) {
	  return element > 10;
	}
	[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
	[12, 5, 8, 1, 4].some(isBiggerThan10); // true
				</pre>
			</div>
			<div>
				<h4 id="map">map</h4>
				<p> 返回一个新数组，它不会检测一个空数组，也不会改变原始数组</p>
				<pre>
	let arr1=[1,2,3,4,5,6]
	let newArr=arr1.map((item)=>{
		return item*2
	})			
				</pre>
			</div>
			<div>
				<h4 id="filter">filter</h4>
				
			</div>
			<div>
				<h4 id="await">遍历按顺序执行</h4>
				<p> for遍历的时候不会按顺序执行，需要配合ES6 async 和 await 方法执行</p>
				<pre>
	const fruits = ["apple", "grape", "pear","bananer","orange"];
	const  ms = (ms)=&gt;{ return new Promise(resolve =&gt; setTimeout(resolve, ms))}
	const   getNumFruit = (fruit) =&gt; {return ms(1000).then(()=&gt;{console.log(fruit)})}
	async function hander (){
		for (let i = 0; i &lt; fruits.length; i ++) {
			const fruit = fruits[i];
			const numFruit = await getNumFruit(fruit);
			console.log(numFruit);
		}
	}
	hander()		
				</pre>
			</div>
		</div>
	</div>
	<!--页面加载进度条-->
	<script src="https://cdn.bootcdn.net/ajax/libs/pace/0.5.0/pace.min.js"></script>
	<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.17/vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		var app = new Vue({
			el: "#app",
			data: function () {
				return {
					list:[
						{name:"for",id:"for",explain:''},
						{name:"forEach",id:"forEach",explain:''},
						{name:"filter()",id:"filter",explain:'过滤'},
						{name:"find()",id:"find",explain:'过滤,'},
						{name:"every()",id:"every",explain:'只要一个不符合条件，返回false'},
						{name:"some()",id:"some",explain:'只有一个符合条件，返回true'},
						{name:"map",id:"map",explain:''},
						{name:"遍历按顺序执行",id:"await",explain:'让遍历可以按顺序执行'},
					]
				}
			},
		})
	</script>
</body>

</html>